﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace Thermometer
{
    [DesignerCategory("Code")]
    public partial class MyThermometer : UserControl
    {
        private float _minValue = -20f;
        private float _maxValue = 100f;
        private float _currentValue = 60f;
        private float _targetValue = 60f;
        private bool _isAnimating = false;
        private Color _thermoColor = Color.FromArgb(52, 152, 219); // 默认蓝色
        private Color _alertColor = Color.FromArgb(231, 76, 60);   // 报警红色
        private Color _borderColor = Color.FromArgb(180, 190, 200);
        private Color _scaleColor = Color.FromArgb(80, 80, 80);
        private Color _textColor = Color.FromArgb(52, 73, 94);
        private float _animationSpeed = 5f;
        private int _bevelSize = 8;
        private float _borderThickness = 1.5f;
        private float _minLimit = 0f;
        private float _maxLimit = 40f;
        private bool _isInAlert = false;

        // 公共属性
        [Category("数据"), Description("温度最小值")]
        public float MinValue
        {
            get => _minValue;
            set { _minValue = value; Invalidate(); }
        }

        [Category("数据"), Description("温度最大值")]
        public float MaxValue
        {
            get => _maxValue;
            set { _maxValue = value; Invalidate(); }
        }

        [Category("数据"), Description("当前温度值")]
        public float CurrentValue
        {
            get => _currentValue;
            set
            {
                value = Math.Max(_minValue, Math.Min(_maxValue, value));
                if (Math.Abs(_currentValue - value) > 0.1f)
                {
                    _targetValue = value;
                    if (!_isAnimating)
                    {
                        _isAnimating = true;
                        animationTimer.Start();
                    }
                }
                else
                {
                    _currentValue = value;
                    Invalidate();
                }

                // 检查报警状态
                CheckAlertStatus();
            }
        }

        [Category("报警设置"), Description("最低温度限制")]
        public float MinLimit
        {
            get => _minLimit;
            set { _minLimit = value; Invalidate(); }
        }

        [Category("报警设置"), Description("最高温度限制")]
        public float MaxLimit
        {
            get => _maxLimit;
            set { _maxLimit = value; Invalidate(); }
        }

        [Category("报警设置"), Description("报警颜色")]
        public Color AlertColor
        {
            get => _alertColor;
            set { _alertColor = value; Invalidate(); }
        }

        [Category("外观"), Description("温度计液体颜色")]
        public Color ThermoColor
        {
            get => _thermoColor;
            set { _thermoColor = value; Invalidate(); }
        }

        [Category("外观"), Description("边框颜色")]
        public Color BorderColor
        {
            get => _borderColor;
            set { _borderColor = value; Invalidate(); }
        }

        [Category("外观"), Description("刻度颜色")]
        public Color ScaleColor
        {
            get => _scaleColor;
            set { _scaleColor = value; Invalidate(); }
        }

        [Category("外观"), Description("文本颜色")]
        public Color TextColor
        {
            get => _textColor;
            set { _textColor = value; Invalidate(); }
        }

        [Category("外观"), Description("动画速度")]
        public float AnimationSpeed
        {
            get => _animationSpeed;
            set { _animationSpeed = Math.Max(1f, value); }
        }

        [Category("外观"), Description("斜面尺寸")]
        public int BevelSize
        {
            get => _bevelSize;
            set { _bevelSize = Math.Max(0, value); Invalidate(); }
        }

        [Category("外观"), Description("边框厚度")]
        public float BorderThickness
        {
            get => _borderThickness;
            set { _borderThickness = Math.Max(0.5f, value); Invalidate(); }
        }

        // 报警状态变化事件
        public event EventHandler AlertStatusChanged;

        // 动画计时器
        private readonly Timer animationTimer;

        public MyThermometer()
        {
            SetStyle(ControlStyles.OptimizedDoubleBuffer |
                     ControlStyles.ResizeRedraw |
                     ControlStyles.UserPaint |
                     ControlStyles.AllPaintingInWmPaint, true);

            Size = new Size(150, 350);
            DoubleBuffered = true;
            Font = new Font("Microsoft YaHei UI", 9f);

            // 初始化动画计时器
            animationTimer = new Timer { Interval = 20 }; // 50fps
            animationTimer.Tick += AnimationTimer_Tick;
        }

        private void CheckAlertStatus()
        {
            bool newAlertStatus = (_currentValue < _minLimit) || (_currentValue > _maxLimit);

            if (newAlertStatus != _isInAlert)
            {
                _isInAlert = newAlertStatus;
                AlertStatusChanged?.Invoke(this, EventArgs.Empty);
                Invalidate();
            }
        }

        private void AnimationTimer_Tick(object sender, EventArgs e)
        {
            // 平滑过渡到目标值
            if (Math.Abs(_currentValue - _targetValue) < 0.1f)
            {
                _currentValue = _targetValue;
                animationTimer.Stop();
                _isAnimating = false;
            }
            else
            {
                _currentValue += (_targetValue - _currentValue) / _animationSpeed;
            }

            CheckAlertStatus();
            Invalidate();
        }

        protected override void OnPaint(PaintEventArgs e)
        {
            base.OnPaint(e);

            var g = e.Graphics;
            g.SmoothingMode = SmoothingMode.AntiAlias;
            g.TextRenderingHint = System.Drawing.Text.TextRenderingHint.ClearTypeGridFit;

            // 绘制背景
            //DrawBackground(g);

            // 计算尺寸
            int padding = 60;
            int paddingTop = 15;
            int thermoWidth = Width - 2 * padding;
            int thermoHeight = Height - 2 * paddingTop - 40;
            int thermoX = padding;
            int thermoY = paddingTop;

            // 绘制温度计主体
            DrawThermometer(g, thermoX, thermoY, thermoWidth, thermoHeight);

            // 绘制当前温度文本
            DrawTemperatureText(g);

            // 绘制温度限制指示器
            DrawLimitIndicators(g, thermoX, thermoY, thermoWidth, thermoHeight);
        }

        private void DrawBackground(Graphics g)
        {
            // 绘制背景渐变
            using (var bgBrush = new LinearGradientBrush(
                ClientRectangle,
                Color.FromArgb(250, 250, 252),
                Color.FromArgb(240, 242, 245),
                90f))
            {
                g.FillRectangle(bgBrush, ClientRectangle);
            }

            // 绘制边框
            using (var borderPen = new Pen(_borderColor, _borderThickness))
            {
                g.DrawRectangle(borderPen,
                    _borderThickness / 2,
                    _borderThickness / 2,
                    Width - _borderThickness,
                    Height - _borderThickness);
            }

            // 绘制内部阴影
            if (_bevelSize > 0)
            {
                using (var highlightPen = new Pen(Color.FromArgb(200, 255, 255, 255), 1))
                {
                    g.DrawLine(highlightPen,
                        _bevelSize, _bevelSize,
                        Width - _bevelSize, _bevelSize);
                    g.DrawLine(highlightPen,
                        _bevelSize, _bevelSize,
                        _bevelSize, Height - _bevelSize);
                }

                using (var shadowPen = new Pen(Color.FromArgb(60, 0, 0, 0), 1))
                {
                    g.DrawLine(shadowPen,
                        Width - _bevelSize, _bevelSize,
                        Width - _bevelSize, Height - _bevelSize);
                    g.DrawLine(shadowPen,
                        _bevelSize, Height - _bevelSize,
                        Width - _bevelSize, Height - _bevelSize);
                }
            }
        }

        private void DrawThermometer(Graphics g, int x, int y, int width, int height)
        {
            // 计算液柱高度 (0-100% 比例)
            float valuePercentage = (_currentValue - _minValue) / (_maxValue - _minValue);
            int liquidHeight = (int)(height * valuePercentage);

            // 确定液柱颜色（报警状态使用报警颜色）
            Color liquidColor = _isInAlert ? _alertColor : _thermoColor;

            // 绘制外框
            using (var framePath = new GraphicsPath())
            {
                // 主体矩形
                framePath.AddRectangle(new Rectangle(x, y, width, height));

                // 底部圆形
                int bulbSize = width + 10;
                int bulbX = x - 5;
                int bulbY = y + height - bulbSize / 2;
                framePath.AddEllipse(bulbX, bulbY, bulbSize, bulbSize);

                // 绘制边框
                using (var framePen = new Pen(_borderColor, 1.5f))
                {
                    g.DrawPath(framePen, framePath);
                }
            }

            // 绘制液柱
            using (var liquidBrush = new LinearGradientBrush(
                new Rectangle(x, y + height - liquidHeight, width, liquidHeight),
                Color.FromArgb(220, liquidColor.R, liquidColor.G, liquidColor.B),
                liquidColor,
                90f))
            {
                // 主体液柱
                int liquidY = y + height - liquidHeight;
                g.FillRectangle(liquidBrush, x + 1, liquidY, width - 2, liquidHeight);

                // 底部圆形液柱
                int bulbSize = width - 2;
                int bulbX = x;
                int bulbY = y + height - bulbSize / 2;
                g.FillEllipse(liquidBrush, bulbX, bulbY, bulbSize, bulbSize);

                // 液柱高光
                using (var highlightBrush = new LinearGradientBrush(
                    new Rectangle(x, liquidY, width / 2, liquidHeight),
                    Color.FromArgb(100, 255, 255, 255),
                    Color.Transparent,
                    0f))
                {
                    g.FillRectangle(highlightBrush, x + 1, liquidY, width / 3, liquidHeight);
                }
            }

            // 绘制刻度
            using (var tickPen = new Pen(_scaleColor, 1.2f))
            using (var font = new Font(Font.FontFamily, 8, FontStyle.Bold))
            using (var brush = new SolidBrush(_textColor))
            {
                int tickCount = 10;
                int tickSpacing = height / tickCount;

                for (int i = 0; i <= tickCount; i++)
                {
                    int tickY = y + height - i * tickSpacing;

                    // 主要刻度
                    if (i % 2 == 0)
                    {
                        // 长刻度线
                        g.DrawLine(tickPen, x - 8, tickY, x, tickY);

                        // 刻度标签
                        float value = _minValue + (i * (_maxValue - _minValue) / tickCount);
                        string label = value.ToString("0");

                        var size = g.MeasureString(label, font);
                        g.DrawString(label, font, brush, x - 10 - size.Width, tickY - size.Height / 2);
                    }
                    else
                    {
                        // 短刻度线
                        g.DrawLine(tickPen, x - 5, tickY, x, tickY);
                    }
                }

                // 绘制当前温度指示器
                int currentY = y + height - liquidHeight;
                using (var indicatorPen = new Pen(Color.Red, 1.5f))
                {
                    g.DrawLine(indicatorPen, x + width, currentY, x + width + 10, currentY);

                    // 绘制指示三角形
                    Point[] triangle = {
                        new Point(x + width + 10, currentY),
                        new Point(x + width + 15, currentY - 4),
                        new Point(x + width + 15, currentY + 4)
                    };
                    g.FillPolygon(Brushes.Red, triangle);
                }

                // 绘制单位标签
                string unit = "°C";
                var unitSize = g.MeasureString(unit, font);
                g.DrawString(unit, font, brush, x + width + 18, y - unitSize.Height);
            }

            // 绘制玻璃高光效果
            using (var highlightPen = new Pen(Color.FromArgb(100, 255, 255, 255), 1.5f))
            {
                // 左侧高光
                g.DrawLine(highlightPen, x + 1, y + 1, x + 1, y + height - 1);

                // 顶部高光
                g.DrawLine(highlightPen, x + 1, y + 1, x + width - 2, y + 1);

                // 球体高光
                int bulbSize = width + 10;
                int bulbX = x - 5;
                int bulbY = y + height - bulbSize / 2;
                g.DrawArc(highlightPen, bulbX + 3, bulbY + 3, bulbSize - 6, bulbSize - 6, 45, 180);
            }
        }

        private void DrawTemperatureText(Graphics g)
        {
            string text = $"{_currentValue:0.0} °C";
            Color displayColor = _isInAlert ? _alertColor : _textColor;

            using (var font = new Font(Font.FontFamily, 10, FontStyle.Bold))
            using (var brush = new SolidBrush(displayColor))
            using (var outlineBrush = new SolidBrush(Color.FromArgb(30, 0, 0, 0)))
            {
                var size = g.MeasureString(text, font);
                float x = (Width - size.Width) / 2;
                float y = Height - size.Height - 2;

                // 绘制主文本
                //g.DrawString(text, font, brush, x, y);

                SizeF textSize = g.MeasureString(text, font);
                RectangleF rect = new RectangleF(x, y, textSize.Width, textSize.Height);

                // 绘制背景和水位值
                using (var backBrush = new SolidBrush(Color.FromArgb(200, Color.White)))
                {
                    g.FillRectangle(backBrush, rect);
                }

                g.DrawString(text, font, Brushes.Black, rect);
            }
        }

        private void DrawLimitIndicators(Graphics g, int thermoX, int thermoY, int thermoWidth, int thermoHeight)
        {
            // 计算限制位置
            float minLimitPercentage = (_minLimit - _minValue) / (_maxValue - _minValue);
            float maxLimitPercentage = (_maxLimit - _minValue) / (_maxValue - _minValue);

            int minY = thermoY + thermoHeight - (int)(thermoHeight * minLimitPercentage);
            int maxY = thermoY + thermoHeight - (int)(thermoHeight * maxLimitPercentage);

            // 绘制最小限制指示器
            using (var minPen = new Pen(Color.FromArgb(120, 52, 152, 219), 1f))
            {
                g.DrawLine(minPen, thermoX, minY, thermoX + thermoWidth, minY);

                // 绘制标签
                using (var font = new Font(Font.FontFamily, 9, FontStyle.Regular))
                using (var brush = new SolidBrush(Color.FromArgb(250, 52, 152, 219)))
                {
                    string label = $"低: {_minLimit:0.#}°C";
                    var size = g.MeasureString(label, font);
                    g.DrawString(label, font, brush, thermoX + thermoWidth + 5, minY - size.Height / 2);
                }
            }

            // 绘制最大限制指示器
            using (var maxPen = new Pen(Color.FromArgb(120, 231, 76, 60), 1f))
            {
                g.DrawLine(maxPen, thermoX, maxY, thermoX + thermoWidth, maxY);

                // 绘制标签
                using (var font = new Font(Font.FontFamily, 9, FontStyle.Regular))
                using (var brush = new SolidBrush(Color.FromArgb(250, 231, 76, 60)))
                {
                    string label = $"高: {_maxLimit:0.#}°C";
                    var size = g.MeasureString(label, font);
                    g.DrawString(label, font, brush, thermoX + thermoWidth + 5, maxY - size.Height / 2);
                }
            }

            // 绘制安全区域
            /*using (var safeBrush = new SolidBrush(Color.FromArgb(30, 46, 204, 113)))
            {
                int safeTop = maxY;
                int safeBottom = minY;
                int safeHeight = safeBottom - safeTop;

                if (safeHeight > 0)
                {
                    g.FillRectangle(safeBrush, thermoX, safeTop, thermoWidth, safeHeight);
                }
            }*/
        }

        protected override void OnResize(EventArgs e)
        {
            base.OnResize(e);
            Invalidate();
        }

        protected override void Dispose(bool disposing)
        {
            if (disposing)
            {
                animationTimer?.Stop();
                animationTimer?.Dispose();
            }
            base.Dispose(disposing);
        }
    }
}
